FVP: Add dummy configs for BL31, BL32 and BL33
authorSoby Mathew <[email protected]>
Wed, 4 Apr 2018 08:40:32 +0000 (09:40 +0100)
committerSoby Mathew <[email protected]>
Mon, 21 May 2018 15:04:16 +0000 (16:04 +0100)
This patch adds soc_fw_config, tos_fw_config and nt_fw_config to the FVP.
The config files are placeholders and do not have any useful bindings
defined. The tos_fw_config is packaged in FIP and loaded by BL2 only
if SPD=tspd. The load address of these configs are specified in tb_fw_config
via new bindings defined for these configs. Currently, in FVP, the
soc_fw_config and tos_fw_config is loaded in the page between BL2_BASE
and ARM_SHARED_RAM. This memory was typically used for BL32 when
ARM_TSP_RAM_LOCATION=tsram but since we cannot fit BL32 in that
space anymore, it should be safe to use this memory for these configs.
There is also a runtime check in arm_bl2_dyn_cfg_init() which ensures
that this overlap doesn't happen.

The previous arm_dyn_get_hwconfig_info() is modified to accept configs
other than hw_config and hence renamed to arm_dyn_get_config_load_info().
The patch also corrects the definition of ARM_TB_FW_CONFIG_LIMIT to be
BL2_BASE.

Change-Id: I03a137d9fa1f92c862c254be808b8330cfd17a5a
Signed-off-by: Soby Mathew <[email protected]>
12 files changed:
include/plat/arm/board/common/board_arm_def.h
include/plat/arm/common/arm_def.h
include/plat/arm/common/arm_dyn_cfg_helpers.h
plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts [new file with mode: 0644]
plat/arm/board/fvp/fdts/fvp_soc_fw_config.dts [new file with mode: 0644]
plat/arm/board/fvp/fdts/fvp_tb_fw_config.dts
plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts [new file with mode: 0644]
plat/arm/board/fvp/platform.mk
plat/arm/common/aarch64/arm_bl2_mem_params_desc.c
plat/arm/common/arm_dyn_cfg.c
plat/arm/common/arm_dyn_cfg_helpers.c
plat/arm/common/arm_io_storage.c

index 845f14037409299f6ba39f3cc82cdca973fe823e..ad6b4f8f58119a25e2c90afa5b191e586eec28d0 100644 (file)
@@ -87,7 +87,7 @@
 #if TRUSTED_BOARD_BOOT
 # define PLAT_ARM_MAX_BL2_SIZE         0x1E000
 #else
-# define PLAT_ARM_MAX_BL2_SIZE         0xF000
+# define PLAT_ARM_MAX_BL2_SIZE         0x10000
 #endif
 
 /*
index 4473b535529d1cf92b24b10bd87852acf4674e12..18390d6a7636dc43ab797201869b438d1266e753 100644 (file)
  * and limit. Leave enough space of BL2 meminfo.
  */
 #define ARM_TB_FW_CONFIG_BASE          ARM_BL_RAM_BASE + sizeof(meminfo_t)
-#define ARM_TB_FW_CONFIG_LIMIT         BL2_LIMIT
+#define ARM_TB_FW_CONFIG_LIMIT         BL2_BASE
 
 /*******************************************************************************
  * BL1 specific defines.
index 826924de0e0e01e6db319e107aea42819c951fa4..382ec6011e9ec0cc7da1c384072df70912e7cd79 100644 (file)
@@ -9,8 +9,8 @@
 #include <stdint.h>
 
 /* Function declaration */
-int arm_dyn_get_hwconfig_info(void *dtb, int node,
-               uint64_t *hw_config_addr, uint32_t *hw_config_size);
+int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
+               uint64_t *config_addr, uint32_t *config_size);
 int arm_dyn_tb_fw_cfg_init(void *dtb, int *node);
 int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth);
 
diff --git a/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_nt_fw_config.dts
new file mode 100644 (file)
index 0000000..7ab980b
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+
+};
diff --git a/plat/arm/board/fvp/fdts/fvp_soc_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_soc_fw_config.dts
new file mode 100644 (file)
index 0000000..7ab980b
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+
+};
index fb7e2c51a00ecdbe237cbad0c5ea92cb356d9cee..716b023778ad2792ac37c378b4c49ad8867f25eb 100644 (file)
                hw_config_addr = <0x0 0x82000000>;
                hw_config_max_size = <0x01000000>;
                /* Disable authentication for development */
-               disable_auth = <0x0>;
+               disable_auth = <0x1>;
+               /*
+                * Load SoC and TOS firmware configs at the base of
+                * non shared SRAM. The runtime checks ensure we don't
+                * overlap BL2, BL31 or BL32. The NT firmware config
+                * is loaded at base of DRAM.
+                */
+               soc_fw_config_addr = <0x0 0x04001000>;
+               soc_fw_config_max_size = <0x200>;
+               tos_fw_config_addr = <0x0 0x04001200>;
+               tos_fw_config_max_size = <0x200>;
+               nt_fw_config_addr = <0x0 0x80000000>;
+               nt_fw_config_max_size = <0x200>;
        };
 };
diff --git a/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_tsp_fw_config.dts
new file mode 100644 (file)
index 0000000..7ab980b
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+
+};
index c5e33d2c6eb05ce46d65058c67b58d908563b9dd..f807dc6e497ef57725638ea092b23b7e43176402 100644 (file)
@@ -166,11 +166,30 @@ BL31_SOURCES              +=      drivers/arm/smmu/smmu_v3.c                      \
 # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env)
 ifdef UNIX_MK
 FVP_HW_CONFIG_DTS      :=      fdts/${FVP_DT_PREFIX}.dts
-FDT_SOURCES            +=      plat/arm/board/fvp/fdts/${PLAT}_tb_fw_config.dts
+FDT_SOURCES            +=      $(addprefix plat/arm/board/fvp/fdts/,   \
+                                       ${PLAT}_tb_fw_config.dts        \
+                                       ${PLAT}_soc_fw_config.dts       \
+                                       ${PLAT}_nt_fw_config.dts        \
+                               )
+
 FVP_TB_FW_CONFIG       :=      ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
+FVP_SOC_FW_CONFIG      :=      ${BUILD_PLAT}/fdts/${PLAT}_soc_fw_config.dtb
+FVP_NT_FW_CONFIG       :=      ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb
+
+ifeq (${SPD},tspd)
+FDT_SOURCES            +=      plat/arm/board/fvp/fdts/${PLAT}_tsp_fw_config.dts
+FVP_TOS_FW_CONFIG      :=      ${BUILD_PLAT}/fdts/${PLAT}_tsp_fw_config.dtb
+
+# Add the TOS_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_TOS_FW_CONFIG},--tos-fw-config))
+endif
 
 # Add the TB_FW_CONFIG to FIP and specify the same to certtool
 $(eval $(call TOOL_ADD_PAYLOAD,${FVP_TB_FW_CONFIG},--tb-fw-config))
+# Add the SOC_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_SOC_FW_CONFIG},--soc-fw-config))
+# Add the NT_FW_CONFIG to FIP and specify the same to certtool
+$(eval $(call TOOL_ADD_PAYLOAD,${FVP_NT_FW_CONFIG},--nt-fw-config))
 
 FDT_SOURCES            +=      ${FVP_HW_CONFIG_DTS}
 $(eval FVP_HW_CONFIG   :=      ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(FVP_HW_CONFIG_DTS)))
index fef01c9d262b26d8d35b5c1972db8f1dfc89393e..8e6d00d056a867020807d84bbbc441cbced47b00 100644 (file)
@@ -91,6 +91,15 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
                    VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
            .next_handoff_image_id = INVALID_IMAGE_ID,
     },
+       /* Fill SOC_FW_CONFIG related information */
+    {
+           .image_id = SOC_FW_CONFIG_ID,
+           SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+           SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+           .next_handoff_image_id = INVALID_IMAGE_ID,
+    },
 # ifdef BL32_BASE
        /* Fill BL32 related information */
     {
@@ -144,6 +153,16 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 #endif
            .next_handoff_image_id = INVALID_IMAGE_ID,
     },
+
+       /* Fill TOS_FW_CONFIG related information */
+    {
+           .image_id = TOS_FW_CONFIG_ID,
+           SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
+           SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+           .next_handoff_image_id = INVALID_IMAGE_ID,
+    },
 # endif /* BL32_BASE */
 
        /* Fill BL33 related information */
@@ -166,6 +185,15 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
 # endif /* PRELOADED_BL33_BASE */
 
            .next_handoff_image_id = INVALID_IMAGE_ID,
+    },
+       /* Fill NT_FW_CONFIG related information */
+    {
+           .image_id = NT_FW_CONFIG_ID,
+           SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, entry_point_info_t, NON_SECURE | NON_EXECUTABLE),
+           SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
+                   VERSION_2, image_info_t, IMAGE_ATTRIB_SKIP_LOADING),
+           .next_handoff_image_id = INVALID_IMAGE_ID,
     }
 #endif /* EL3_PAYLOAD_BASE */
 };
index 33dc08b9ec5274c79e95c0bb00e4142e96bd9335..3f0a9b4cfbbc8fedc22f129dde0805a1b2948204 100644 (file)
@@ -85,14 +85,25 @@ void arm_bl2_set_tb_cfg_addr(void *dtb)
 
 /*
  * BL2 utility function to initialize dynamic configuration specified by
- * TB_FW_CONFIG. Return early if TB_FW_CONFIG is not found or HW_CONFIG is
- * not specified in TB_FW_CONFIG.
+ * TB_FW_CONFIG. Populate the bl_mem_params_node_t of other FW_CONFIGs if
+ * specified in TB_FW_CONFIG.
  */
 void arm_bl2_dyn_cfg_init(void)
 {
-       int err = 0;
-       int tb_fw_node;
-       bl_mem_params_node_t *hw_cfg_mem_params = NULL;
+       int err = 0, tb_fw_node;
+       unsigned int i;
+       bl_mem_params_node_t *cfg_mem_params = NULL;
+       uint64_t image_base;
+       uint32_t image_size;
+       const unsigned int config_ids[] = {
+                       HW_CONFIG_ID,
+                       SOC_FW_CONFIG_ID,
+                       NT_FW_CONFIG_ID,
+#ifdef SPD_tspd
+                       /* Currently tos_fw_config is only present for TSP */
+                       TOS_FW_CONFIG_ID
+#endif
+       };
 
        if (tb_fw_cfg_dtb == NULL) {
                VERBOSE("No TB_FW_CONFIG specified\n");
@@ -105,23 +116,57 @@ void arm_bl2_dyn_cfg_init(void)
                panic();
        }
 
-       /* Get the hw_config load address and size from TB_FW_CONFIG */
-       hw_cfg_mem_params = get_bl_mem_params_node(HW_CONFIG_ID);
-       if (hw_cfg_mem_params == NULL) {
-               VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n");
-               return;
-       }
+       /* Iterate through all the fw config IDs */
+       for (i = 0; i < ARRAY_SIZE(config_ids); i++) {
+               /* Get the config load address and size from TB_FW_CONFIG */
+               cfg_mem_params = get_bl_mem_params_node(config_ids[i]);
+               if (cfg_mem_params == NULL) {
+                       VERBOSE("Couldn't find HW_CONFIG in bl_mem_params_node\n");
+                       continue;
+               }
+
+               err = arm_dyn_get_config_load_info((void *)tb_fw_cfg_dtb, tb_fw_node,
+                               config_ids[i], &image_base, &image_size);
+               if (err < 0) {
+                       VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
+                                       config_ids[i]);
+                       continue;
+               }
+
+               /*
+                * Do some runtime checks on the load addresses of soc_fw_config,
+                * tos_fw_config, nt_fw_config. This is not a comprehensive check
+                * of all invalid addresses but to prevent trivial porting errors.
+                */
+               if (config_ids[i] != HW_CONFIG_ID) {
+
+                       if (check_uptr_overflow(image_base, image_size) != 0)
+                               continue;
+
+                       /* Ensure the configs don't overlap with BL2 */
+                       if ((image_base > BL2_BASE) || ((image_base + image_size) > BL2_BASE))
+                               continue;
+
+                       /* Ensure the configs are loaded in a valid address */
+                       if (image_base < ARM_BL_RAM_BASE)
+                               continue;
+#ifdef BL32_BASE
+                       /*
+                        * If BL32 is present, ensure that the configs don't
+                        * overlap with it.
+                        */
+                       if (image_base >= BL32_BASE && image_base <= BL32_LIMIT)
+                               continue;
+#endif
+               }
 
-       err = arm_dyn_get_hwconfig_info((void *)tb_fw_cfg_dtb, tb_fw_node,
-               (uint64_t *) &hw_cfg_mem_params->image_info.image_base,
-               &hw_cfg_mem_params->image_info.image_max_size);
-       if (err < 0) {
-               VERBOSE("Couldn't find HW_CONFIG load info in TB_FW_CONFIG\n");
-               return;
-       }
 
-       /* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */
-       hw_cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+               cfg_mem_params->image_info.image_base = (uintptr_t)image_base;
+               cfg_mem_params->image_info.image_max_size = image_size;
+
+               /* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */
+               cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
+       }
 
 #if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
        uint32_t disable_auth = 0;
index e37e7e72202a147ea73ffbdb415fa5b3b23b71d1..5a7e20ac8e2cd52af8abd541be6c7fa37428ddc3 100644 (file)
 #include <libfdt.h>
 #include <plat_arm.h>
 
+
+typedef struct config_load_info_prop {
+       unsigned int config_id;
+       const char *config_addr;
+       const char *config_max_size;
+} config_load_info_prop_t;
+
+static const config_load_info_prop_t prop_names[] = {
+       {HW_CONFIG_ID, "hw_config_addr", "hw_config_max_size"},
+       {SOC_FW_CONFIG_ID, "soc_fw_config_addr", "soc_fw_config_max_size"},
+       {TOS_FW_CONFIG_ID, "tos_fw_config_addr", "tos_fw_config_max_size"},
+       {NT_FW_CONFIG_ID, "nt_fw_config_addr", "nt_fw_config_max_size"}
+};
+
 /*******************************************************************************
- * Helper to read the `hw_config` property in config DTB. This function
- * expects the following properties to be present in the config DTB.
- *     name : hw_config_addr           size : 2 cells
- *     name : hw_config_max_size       size : 1 cell
+ * Helper to read the load information corresponding to the `config_id` in
+ * TB_FW_CONFIG. This function expects the following properties to be defined :
+ *     <config>_addr           size : 2 cells
+ *     <config>_max_size       size : 1 cell
  *
  * Arguments:
  *     void *dtb                - pointer to the TB_FW_CONFIG in memory
  *     int node                 - The node offset to appropriate node in the
  *                                      DTB.
- *     uint64_t *hw_config_addr - Returns the `hw_config` load address if read
+ *     unsigned int config_id   - The configuration id
+ *     uint64_t *config_addr    - Returns the `config` load address if read
  *                                      is successful.
- *     uint32_t *hw_config_size - Returns the `hw_config` size if read is
+ *     uint32_t *config_size    - Returns the `config` size if read is
  *                                      successful.
  *
  * Returns 0 on success and -1 on error.
  ******************************************************************************/
-int arm_dyn_get_hwconfig_info(void *dtb, int node,
-               uint64_t *hw_config_addr, uint32_t *hw_config_size)
+int arm_dyn_get_config_load_info(void *dtb, int node, unsigned int config_id,
+               uint64_t *config_addr, uint32_t *config_size)
 {
        int err;
+       unsigned int i;
 
        assert(dtb != NULL);
-       assert(hw_config_addr != NULL);
-       assert(hw_config_size != NULL);
+       assert(config_addr != NULL);
+       assert(config_size != NULL);
+
+       for (i = 0; i < ARRAY_SIZE(prop_names); i++) {
+               if (prop_names[i].config_id == config_id)
+                       break;
+       }
+
+       if (i == ARRAY_SIZE(prop_names)) {
+               WARN("Invalid config id %d\n", config_id);
+               return -1;
+       }
 
        /* Check if the pointer to DT is correct */
        assert(fdt_check_header(dtb) == 0);
@@ -43,22 +69,22 @@ int arm_dyn_get_hwconfig_info(void *dtb, int node,
        /* Assert the node offset point to "arm,tb_fw" compatible property */
        assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"));
 
-       err = fdtw_read_cells(dtb, node, "hw_config_addr", 2,
-                               (void *) hw_config_addr);
+       err = fdtw_read_cells(dtb, node, prop_names[i].config_addr, 2,
+                               (void *) config_addr);
        if (err < 0) {
-               WARN("Read cell failed for hw_config_addr\n");
+               WARN("Read cell failed for %s\n", prop_names[i].config_addr);
                return -1;
        }
 
-       err = fdtw_read_cells(dtb, node, "hw_config_max_size", 1,
-                               (void *) hw_config_size);
+       err = fdtw_read_cells(dtb, node, prop_names[i].config_max_size, 1,
+                               (void *) config_size);
        if (err < 0) {
-               WARN("Read cell failed for hw_config_max_size\n");
+               WARN("Read cell failed for %s\n", prop_names[i].config_max_size);
                return -1;
        }
 
-       VERBOSE("Dyn cfg: Read hw_config address from TB_FW_CONFIG 0x%p %p\n",
-                               hw_config_addr, hw_config_size);
+       VERBOSE("Dyn cfg: Read config_id %d load info from TB_FW_CONFIG 0x%llx 0x%x\n",
+                               config_id, (unsigned long long)*config_addr, *config_size);
 
        return 0;
 }
@@ -98,7 +124,7 @@ int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth)
        }
 
        /* Check if the value is boolean */
-       if (*disable_auth != 0 && *disable_auth != 1) {
+       if ((*disable_auth != 0U) && (*disable_auth != 1U)) {
                WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth);
                return -1;
        }
index 652f5e95eeb2696eca26901d2bf9b01d6919d997..cd58e4564ac3a0f749f4c81b2739d1defcef70d2 100644 (file)
@@ -63,6 +63,18 @@ static const io_uuid_spec_t hw_config_uuid_spec = {
        .uuid = UUID_HW_CONFIG,
 };
 
+static const io_uuid_spec_t soc_fw_config_uuid_spec = {
+       .uuid = UUID_SOC_FW_CONFIG,
+};
+
+static const io_uuid_spec_t tos_fw_config_uuid_spec = {
+       .uuid = UUID_TOS_FW_CONFIG,
+};
+
+static const io_uuid_spec_t nt_fw_config_uuid_spec = {
+       .uuid = UUID_NT_FW_CONFIG,
+};
+
 #if TRUSTED_BOARD_BOOT
 static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
        .uuid = UUID_TRUSTED_BOOT_FW_CERT,
@@ -167,6 +179,21 @@ static const struct plat_io_policy policies[] = {
                (uintptr_t)&hw_config_uuid_spec,
                open_fip
        },
+       [SOC_FW_CONFIG_ID] = {
+                       &fip_dev_handle,
+                       (uintptr_t)&soc_fw_config_uuid_spec,
+                       open_fip
+       },
+       [TOS_FW_CONFIG_ID] = {
+               &fip_dev_handle,
+               (uintptr_t)&tos_fw_config_uuid_spec,
+               open_fip
+       },
+       [NT_FW_CONFIG_ID] = {
+               &fip_dev_handle,
+               (uintptr_t)&nt_fw_config_uuid_spec,
+               open_fip
+       },
 #if TRUSTED_BOARD_BOOT
        [TRUSTED_BOOT_FW_CERT_ID] = {
                &fip_dev_handle,